/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/*!
  \file nodeIconManager.h
  \author Cory Dixon
*/

#ifndef __FP_LAYER_MANAGER_H
#define __FP_LAYER_MANAGER_H

#include "LayerManager.h"

/*<-------Defines--------->*/
#define MAX_PREV_LINE 3
/*<------End Defines------>*/

typedef struct _ImgAlloc_t {
	double x; double y; //coordinates of group, evertying else is reletive to the group
	GooCanvasItem *pointG;
	GooCanvasItem *point;
	GooCanvasItem *text;
	GooCanvasItem *orbit;
	GooCanvasItem *line_prev[MAX_PREV_LINE];
	GooCanvasItem *line_next;
	_ImgAlloc_t() { 
		pointG = point = text = orbit = line_next = NULL; 
		for(int i=0; i < MAX_PREV_LINE; i++) line_prev[i] = NULL;
	}
} ImgAlloc_t;

typedef struct _FlightPlanAlloc {
	uint8_t         last_wp;
	uint8_t         current_wp;
	GooCanvasItem  *wp_group;
	char            color_str[32];

	GPSWaypointPlan   plan;
	WPMask_t          editing_mask;

	ImgAlloc_t imgPoints[NUM_WP_POINTS];

	_FlightPlanAlloc() { wp_group = NULL; }

} FlightPlanAlloc;


class FPManager : public LayerManager
{
	protected:
		// GPS flight plans
		FlightPlanAlloc wpPlans[MAX_CLIENTS+1];

		double pointWidth;
		double lineWidth;

		double mouse_x;
		double mouse_y;
		int    mouse_fp_ind;
		int    mouse_wp_ind;
		double last_theta;

		int    drag_client;
		int    drag_point;    // true if dragging an individual point
		bool   drag_plan;     // true if dragging plan
		bool   rotate_plan;   // true if rotating plan
		bool   dragging;      // true if dragging a plan related item
		bool   creating_plan; // true if creating a local plan

		void translate_point(int clientInd, int pointInd, double dX, double dY);
		void rotate_point(int clientInd, int pointInd, double dTheta);
		void setModified(int clientInd, int wp_ind);

		// menu  widget
		GtkWidget      *menu;
		GtkActionGroup *action_group;          /* Packing group for our Actions */
		GtkUIManager   *menu_manager;          /* The magic widget! */

		// flight plan editin
		GtkWidget      *fp_editor;

		// sending flight plans to clients
		GtkWidget      *fp_send;
		GtkWidget      *fps_sw;
		GtkWidget      *fps_alt;
		GtkWidget      *fps_index;
		GtkListStore   *fps_list_store;
		GtkTreeView    *fps_treeview;

		GtkTreeView *create_fps_tree(GtkTreeView *view, GtkWidget *sw);
		GtkTreeView *format_fps_treeview();

		// default take-off plan
		GtkTreeView    *to_treeview;
		GtkWidget      *to_win;
		GtkWidget      *to_index;
		GtkWidget      *to_height;
		GtkWidget      *to_width;
		GtkWidget      *to_alt;
		GtkWidget      *to_sw;

		// default lost-comm plan
		GtkTreeView    *lc_treeview;
		GtkWidget      *lc_win;
		GtkWidget      *lc_index;
		GtkWidget      *lc_radius;
		GtkWidget      *lc_dir;
		GtkWidget      *lc_alt;
		GtkWidget      *lc_sw;
	
		void update_client_list();

	public:
		FPManager();
		~FPManager();

		virtual void init(GPSMap *map = NULL);
		virtual void updateMap();
		virtual void translate_from_zoomChange(double zoom_factor);

		// functions for the flight plan layer
		void setup_item(GooCanvasItem *item);

		bool add_waypoint(int clientInd, GPSWaypoint_t &point) {
			return wpPlans[clientInd].plan.add_waypoint(point);
		}
		int numPoints(int clientInd) {
			return wpPlans[clientInd].plan.numPoints();
		}
		GPSWaypoint_t get_waypoint(int clientInd, uint8_t ind) {
			return wpPlans[clientInd].plan.get_waypoint(ind);
		}
		bool set_waypoint(int clientInd, GPSWaypoint_t &point) {
			return wpPlans[clientInd].plan.set_waypoint(point);
		}
		void setPlanEditing(bool val) {
			creating_plan = val;
		}

		bool add_flightplan(int clientInd, String file);  // true if file loaded 
		bool save_flightplan(int clientInd, int fpInd, String wpfile); // true if file saved
		bool send_flightplan(int clientInd, int toInd, int fpInd, int wpStartInd = -1, float planAlt = -1.0); // true if sent out socket 
		bool read_from_cmd(int clientInd, uint8_t * buf);
		void create_canvas_flightplan(int clientInd);

		// create default plans based on location of vcgui
		void create_default_to_plan();
		void create_default_lost_comm_plan();

		void clear_client(int clientInd = MAX_CLIENTS);
		void clear_client_canvas(int clientInd = MAX_CLIENTS);

		static bool button_press_event_cb(GooCanvasItem *item, GooCanvasItem *target_item, 
				GdkEventButton *event, FPManager *me);
		static bool button_release_event_cb(GooCanvasItem *item, GooCanvasItem *target_item, 
				GdkEventButton *event, FPManager *me);
		static bool motion_notify_event_cb(GooCanvasItem *item, GooCanvasItem *target_item, 
				GdkEventMotion *event, FPManager *me);

		int create_control_window( GdkEventButton *event );
		static int edit_fp_cb(GtkAction *action, FPManager *me);
		static int copy_fp_cb(GtkAction *action, FPManager *me);
		static int send_fp_cb(GtkAction *action, FPManager *me);
		static int save_fp_cb(GtkAction *action, FPManager *me);
		static int clear_fp_cb(GtkAction *action, FPManager *me);

		void create_fpsend_window();
		static void fpsend_button_clicked (GtkButton *button, gpointer user_data);
		static gboolean fpsend_window_destroy(GtkWidget * widget, GdkEventKey * event, gpointer user_data);

		void create_fpeditor_window();
		static void fpeditor_button_clicked (GtkButton *button, gpointer user_data);
		static gboolean fpeditor_window_destroy(GtkWidget * widget, GdkEventKey * event, gpointer user_data);

		void create_model_and_view(void);
		void fill_model(void);
		static void cell_edited_callback (GtkCellRendererText *cell, gchar *path_string, gchar *new_text, gpointer user_data);
		static void cell_toggled_callback (GtkCellRendererToggle *cell, gchar *path_string, gpointer user_data);

		GtkWidget    *list_view;
		GtkListStore *list_store;
		GtkTreeModel *list_model;

		/* columns */
		typedef enum
		{
			COL_INDEX=0,
			COL_NEXT,
			COL_LAT,
			COL_LON,
			COL_ALT,
			//COL_WINDINTERVAL,
			//COL_PRETURN,
			//COL_LIGHTS,
			//COL_SLOPE,
			//COL_LAND,
			//COL_PARACHUTE,
			//COL_DROP,
			//COL_CAMERA,
			//COL_HOVER,
			COL_ORBITDIRECTION,
			COL_ORBITRADIUS,
			//COL_ORBITTIME,
			//COL_ORBITABOVEALT,
			//COL_ORBITBELOWALT,
			//COL_USER,
			NUM_COLUMNS
		} ColType;

		typedef struct _TreeStruct_t{
			ColType col;
			const char *name;
			guint type;
		} TreeStruct_t;
		static TreeStruct_t wp_entries[NUM_COLUMNS];
			
};

#endif
